﻿@inherits BaseDataEditor

@if (Options != null)
{
    <select class="form-control @(CssHelper.GetValidationClass(State))"
            disabled=@IsDisabled
            @onchange=@OnChange
            value="@SelectedIndex">
        @if (IsNullable)
        {
            <option value="-1">&nbsp;</option>
        }
        @foreach (var (option, index) in Options.Select((o, i) => (o, i)))
        {
            <option value=@index>@option.Labels.First()</option>
        }
    </select>

    @foreach (var message in GetValidationMessages())
    {
        <div class="invalid-feedback">
            @message
        </div>
    }
}
@code {

    private IEnumerable<IElement>? Options;
    private int SelectedIndex = -1;

    private bool IsNullable;

    protected override async Task OnInitializedAsync()
    {
        if (DataCollection != null)
        {
            DataCollection.OnDataChange += async (s, a) => await UpdateOptionsAsync();

            IsNullable = Nullable.GetUnderlyingType(Property.PropertyType) != null;

            var value = GetValueAsObject();

            await DataCollection.SetEntityAsync(EditContext, Parent);
            await UpdateOptionsAsync();

            var list = Options?.ToList();

            SelectedIndex = list?.FindIndex(option => option.Id.Equals(value)) ?? -1;

            if (SelectedIndex == -1)
            {
                // make dropdown nullable for current non-selection
                IsNullable = true;
            }
        }
    }

    private async Task UpdateOptionsAsync()
    {
        if (DataCollection == null)
        {
            return;
        }

        await InvokeAsync(async () =>
        {
            Options = await DataCollection.GetAvailableElementsAsync();
            StateHasChanged();
        });
    }

    private void OnChange(ChangeEventArgs args)
    {
        var index = int.Parse((string)args.Value);

        if (index == -1)
        {
            SetValueFromObject(default);
        }
        else
        {
            SetValueFromObject(Options.ElementAt(index).Id);
        }

        // reset nullable when option is selected
        if (Nullable.GetUnderlyingType(Property.PropertyType) == null && IsNullable)
        {
            IsNullable = false;

            StateHasChanged();
        }
    }
}